package edu.dublbo.app.generator.advice;

import edu.dublbo.app.generator.advice.exception.OptErrorException;
import edu.dublbo.app.generator.result.OptStatus;
import edu.dublbo.app.generator.result.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 统一校验异常处理
 *
 * @author DubLBo
 * @since 2020-09-06 11:23
 * i believe i can i do
 */

@RestControllerAdvice
public class ExceptionAdvice {
    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    /**
     * 处理数据绑定异常
     *
     * @param bindException 数据绑定异常
     * @return 统一响应基本结果
     */
    @ExceptionHandler(value = BindException.class)
    public ResponseEntity<Result<Object>> handleValidateException(BindException bindException) {
        logger.error("数据绑定异常，{}", bindException.getMessage(), bindException);
        return of(HttpStatus.BAD_REQUEST, "数据绑定异常");
    }


    /**
     * 统一处理 405 异常
     *
     * @param exception 请求方法不支持异常
     * @return 统一响应结果
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ResponseEntity<Result<Object>> handleMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        if (exception != null) {
            logger.error("Http 405, {}", exception.getMessage(), exception);
        }

        return of(HttpStatus.METHOD_NOT_ALLOWED, "方法不被支持");

    }

    private ResponseEntity<Result<Object>> of(HttpStatus status, String msg) {
        return ResponseEntity.status(status).body(Result.builder().code(OptStatus.FAIL.code).msg(msg).build());
    }

    /**
     * 统一处理自定义操作错误异常
     *
     * @param exception 操作错误异常
     * @return 统一响应结果
     */
    @ExceptionHandler(value = OptErrorException.class)
    public ResponseEntity<Result<Object>> handleOptErrorException(OptErrorException exception) {
        return of(HttpStatus.INTERNAL_SERVER_ERROR, exception.getOptMsg());
    }

    /**
     * 统一处理 服务器内部 异常
     *
     * @param e 异常
     * @return 统一响应结果
     */
    @ExceptionHandler(value = Throwable.class)
    public ResponseEntity<Result<Object>> handle500(Throwable e) {
        if (e != null) {
            logger.error("Http 500, {}", e.getMessage(), e);
        }
        return of(HttpStatus.INTERNAL_SERVER_ERROR, "服务器内部未知错误");
    }

}
